//
//  QFMultimedia.m
//
//  Created by 祁小斐 on 14-5-29.
//  Copyright (c) 2014年 祁小斐. All rights reserved.
//

#import "QFMultimedia.h"
#import <AssetsLibrary/AssetsLibrary.h>


/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark - 多媒体操作

@interface QFMultimedia () {
    ALAssetsLibrary *assetsLibrary;
}
@property (nonatomic, copy) WriteImageToPhotosAlbumBlock imageBlock;
@property (nonatomic, copy) WriteVideoToPhotosAlbumBlock videoBlock;

@end

@implementation QFMultimedia


- (void)dealloc
{
    assetsLibrary = nil;
    self.imageBlock = nil;
    self.videoBlock = nil;
}

+ (BOOL) isJPEG:(NSData *)data{
    
    if (data == nil || [data length] < 4){
        return NO;
    }
    const unsigned char * bytes = (const unsigned char *)[data bytes];
    if (bytes[0] != 0xFF || bytes[1] != 0xD8) {
        return NO;
    }
    
    if (bytes[[data length] - 2] != 0xFF || bytes[[data length] - 1] != 0xD9) {
        return NO;
    }
    return YES;
}

+ (BOOL)isPNG:(NSData *)data
{
    if (data == nil || [data length]<8) {
        return NO;
    }
    Byte pngHead[] = {0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a};//文件头数据
    int cmpResult = memcmp(data.bytes, pngHead, 8);//判断是否为png格式
    if (cmpResult == 0) {
        return YES;
    }
    return NO;
}

+ (UIImage *) compressTo2K:(UIImage *)image{
    CGFloat length = 0;
    if (image.size.width > image.size.height) {
        length = image.size.width;
    } else {
        length = image.size.height;
    }
    CGFloat ratio = 1;
    if (length > 2048) {
        ratio = 2048.0/length;
    }
    return [self compress:image ratio:ratio];
}

+ (NSData *) compressTo2K:(UIImage *)image quality:(CGFloat)quality{
    return [self compress:[self compressTo2K:image] ratio:1 quality:quality];
}

+ (UIImage *) compress:(UIImage *)image ratio:(CGFloat)ratio{
    if (ratio <= 0 || ratio > 1) {
        ratio = 1;
    }
    return [QFMultimedia compress2:image size:CGSizeMake((int)(image.size.width * ratio), (int)(image.size.height * ratio))];
}

// 改变图片尺寸1 有时候图片会反转
+ (UIImage *) compress:(UIImage *)image size:(CGSize)size {
    CGFloat destW = size.width;
    CGFloat destH = size.height;
    CGFloat sourceW = size.width;
    CGFloat sourceH = size.height;
    CGImageRef imageRef = image.CGImage;
    CGContextRef bitmap = CGBitmapContextCreate(NULL, destW,  destH,  CGImageGetBitsPerComponent(imageRef),  4*destW, CGImageGetColorSpace(imageRef), (kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst));
    CGContextDrawImage(bitmap, CGRectMake(0, 0, sourceW, sourceH), imageRef);
    CGImageRef ref = CGBitmapContextCreateImage(bitmap);
    UIImage *newImage = [UIImage imageWithCGImage:ref];
    CGContextRelease(bitmap);
    CGImageRelease(ref);
    return newImage;
}

// 改变图片尺寸2
+ (UIImage *)compress2:(UIImage *)image size:(CGSize)size
{
    UIImage *newImage = nil;
    CGSize imageSize = image.size;
    CGFloat width = imageSize.width;
    CGFloat height = imageSize.height;
    CGFloat targetWidth = size.width;
    CGFloat targetHeight = size.height;
    CGFloat scaleFactor = 0.0;
    CGFloat scaledWidth = targetWidth;
    CGFloat scaledHeight = targetHeight;
    CGPoint thumbnailPoint = CGPointMake(0.0,0.0);
    if (CGSizeEqualToSize(imageSize, size) == NO) {
        CGFloat widthFactor = targetWidth / width;
        CGFloat heightFactor = targetHeight / height;
        if (widthFactor < heightFactor)
            scaleFactor = widthFactor;
        else
            scaleFactor = heightFactor;
        scaledWidth  = width * scaleFactor;
        scaledHeight = height * scaleFactor;
        if (widthFactor < heightFactor) {
            
            thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5;
        } else if (widthFactor > heightFactor) {
            thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5;
        }
    }
    UIGraphicsBeginImageContext(size);
    CGRect thumbnailRect = CGRectZero;
    thumbnailRect.origin = thumbnailPoint;
    thumbnailRect.size.width  = scaledWidth;
    thumbnailRect.size.height = scaledHeight;
    [image drawInRect:thumbnailRect];
    newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return newImage ;
}

+ (NSData *) compress:(UIImage *)image ratio:(CGFloat)ratio quality:(CGFloat)quality {
    if (ratio <= 0 || ratio > 1) {
        ratio = 1;
    }
    return [QFMultimedia compress:image quality:quality size:CGSizeMake((int)(image.size.width * ratio),(int)(image.size.height * ratio))];
}

+ (NSData *) compress:(UIImage *)image quality:(CGFloat)quality size:(CGSize)size{
    if (quality <= 0 || quality > 1) {
        quality = 1;
    }
    UIImage *newImage = [QFMultimedia compress2:image size:size];
    NSData *data = UIImageJPEGRepresentation(newImage, quality);
    if ([QFMultimedia isJPEG:data] ) {
        return data;
    }
    data = UIImagePNGRepresentation(newImage);
    if ([QFMultimedia isPNG:data]){
        return data;
    }
    return nil;
}



- (void) writeImageToPhotosAlbum:(UIImage *)image usingBlock:(WriteImageToPhotosAlbumBlock)block{
    self.imageBlock = block;
    UIImageWriteToSavedPhotosAlbum(image, self,@selector(image:didFinishSavingWithError:contextInfo:), NULL);
}

- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo{
    if (self.imageBlock) {
        self.imageBlock(image,error,contextInfo);
    } else{
        if (!error) {
            NSLog(@"照片保存成功");
        }
    }
}

- (void) writeVideoToPhotosAlbum:(NSString *)videoPath usingBlock:(WriteVideoToPhotosAlbumBlock)block{
    self.videoBlock = block;
    UISaveVideoAtPathToSavedPhotosAlbum(videoPath, self, @selector(video:didFinishSavingWithError:contextInfo:), NULL);
}

- (void)video:(NSString *)videoPath didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo{
    if (self.videoBlock) {
        self.videoBlock(videoPath,error,contextInfo);
    } else{
        if (!error) {
            NSLog(@"视频保存成功");
        }
    }
}

- (void) traversePhotosAlbum:(QFFileType)fileType findAFile:(FindAFileBlock)block {
    __block QFMultimedia *bself = self;
    if (assetsLibrary == nil) {
        assetsLibrary = [[ALAssetsLibrary alloc] init];
    }
    [assetsLibrary enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
        [group enumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {
            QFAsset *entity = nil;
            NSString *assetType = [result valueForProperty:ALAssetPropertyType];
            if (fileType == QFFileTypeImage && [assetType isEqualToString:ALAssetTypePhoto]) {
                entity = [bself getPhotosAlbumFileEntityByAsset:result];
            } else if (fileType == QFFileTypeVideo && [assetType isEqualToString:ALAssetTypeVideo]) {
                entity = [bself getPhotosAlbumFileEntityByAsset:result];
            } else if (fileType == QFFileTypeALL){
                if ([assetType isEqualToString:ALAssetTypeUnknown]) {
                    NSLog(@"相册中有一个未知类型文件");
                } else {
                    entity = [bself getPhotosAlbumFileEntityByAsset:result];
                }
            }
            if (entity) {
                block(entity);
            }
        }];

    } failureBlock:^(NSError *error) {
        block(nil);
    }];

}

- (QFAsset *) getPhotosAlbumFileEntityByAsset:(ALAsset *)asset{
    
    ALAssetRepresentation *representation = [asset defaultRepresentation];
    if (representation.size <= 0){
        return nil;
    }
    QFAsset *entity = [[QFAsset alloc] init];
    // url
    entity.url = representation.url;
    NSArray *urlParams = [[entity.url query] componentsSeparatedByString:@"&"];
    for (NSString *param in urlParams) {
        if ([param rangeOfString:@"id"].length > 0) {
            // 文件ID
            entity.fileID = [param stringByReplacingOccurrencesOfString:@"id=" withString:@""];
        }
    }
    // 文件名
    entity.fileName = [representation.filename componentsSeparatedByString:@"."][0];
    // 创建日期
    entity.createDate = [asset valueForProperty:ALAssetPropertyDate];
    
    if (entity.fileName == nil && entity.createDate == nil) {
        return nil;
    }
    // 字节数
    entity.size = representation.size;
    
    
    // 播放时间
    NSString *duration = [NSString stringWithFormat:@"%@",[asset valueForProperty:ALAssetPropertyDuration]];
    if ([duration isEqualToString:ALErrorInvalidProperty]) {
        entity.duration = @"";
    } else {
        entity.duration = [self translationDurationToVideoTimeString:duration.integerValue];
    }
    // 缩略图
    entity.thumbnail = [UIImage imageWithCGImage:asset.thumbnail];

//    long long length = (long long)entity.representation.size;// 文件大小,单位bytes
//    uint8_t *buffer = (Byte *) malloc(length);
//    NSUInteger dataLength = [entity.representation getBytes:buffer fromOffset:0.0  length:length error:nil];
//    [[[NSData alloc] initWithBytesNoCopy:buffer length:dataLength freeWhenDone:YES] autorelease];
//    NSString *url = [mediaOBJ valueForProperty:ALAssetPropertyAssetURL];//获取url第1种方式
//    NSURL *url = representation.url; //获取url第2种方式
//    NSDate *date = [mediaOBJ valueForProperty:ALAssetPropertyDate];
//    ALAssetRepresentation *representation = [mediaOBJ defaultRepresentation];
//    CGSize size = representation.dimensions;// 原图或原视频 的分辩率 例:720:1280

//    NSDictionary *dic = representation.metadata;// 照片像素信息,视频返回nil
//    NSDictionary *dic1 = dic[@"{TIFF}"];
//    NSDictionary *dic2 = dic[@"{Exif}"];
//    float scale = representation.scale;// 比例
//    NSString *fileName = representation.filename;// 文件名
    
    
    return entity;
}

- (void) writeFileWithURL:(NSURL *)url toPath:(NSString *)path progressBlock:(ProgressBlock)progressBlock completeBlock:(WriteCompleteBlock)completeBlock{
    if (assetsLibrary == nil) {
        assetsLibrary = [[ALAssetsLibrary alloc] init];
    }
    
    if ([[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:nil]) {
        completeBlock(nil);
        return;
    }
    
    [assetsLibrary assetForURL:url resultBlock:^(ALAsset *asset) {
        ALAssetRepresentation *assetRep = [asset defaultRepresentation];
        long long size = [assetRep size];
        if (size <= 0) {
            completeBlock([NSError errorWithDomain:@"失效" code:0 userInfo:nil]);
            return ;
        }
        
        NSError *err = nil;
        NSOutputStream *outputStream = [NSOutputStream outputStreamToFileAtPath:path append:NO];
        [outputStream open];
    
        NSInteger dataLength;
        NSInteger bytesWritten;
        NSInteger bytesWrittenSoFar;
        NSInteger bytesWrittenSize;
        
        NSInteger avgSize = 0;
        if ([UIDevice currentDevice].systemVersion.floatValue >= 7.0) {
            avgSize = 1024*1024*3; //缓存 3M
        } else {
            avgSize = 1024*1024; //缓存 1M
        }
        
        NSInteger totalCount = 0;
        
        if (avgSize >= size) {
            totalCount = 1;
            avgSize = (NSInteger)size;
        }else{
            totalCount = (NSInteger)(size/avgSize + 1);
        }
        
        float temp = 0.0;
        for (int i=1; i<= totalCount; i++) {
            bytesWrittenSize = i != totalCount ? avgSize : (NSInteger)(size-(i-1)*avgSize);
            uint8_t * buffer = malloc(bytesWrittenSize);
            NSUInteger gotByteCount = [assetRep getBytes:buffer  fromOffset:(i-1)*avgSize length:bytesWrittenSize error:&err];
            
            dataLength = bytesWrittenSize;
            bytesWrittenSoFar = 0;
            do {
                bytesWritten = [outputStream write:&buffer[bytesWrittenSoFar] maxLength:dataLength - bytesWrittenSoFar];
                assert(bytesWritten != 0);
                if (bytesWritten == -1) {
                    NSLog(@"File write error");
                    break;
                } else {
                    bytesWrittenSoFar += bytesWritten;
                    if(progressBlock) progressBlock(temp/size);
                }
            } while (bytesWrittenSoFar != dataLength);
            
            free(buffer);
            temp += gotByteCount;
        }
        [outputStream close];
        completeBlock(nil);
    } failureBlock:^(NSError *error) {
        completeBlock(error);
    }];
    
}

#pragma mark 视频时长 秒数 转化成 00:00:00 格式
- (NSString *) translationDurationToVideoTimeString:(long) second{
    if (second < 60) {
        if (second % 60 < 10) {
            return [NSString stringWithFormat:@"00:0%ld",second%60];
        }
        return [NSString stringWithFormat:@"00:%ld",second];
    } else if (second < 600) {
        if (second % 60 < 10) {
            return [NSString stringWithFormat:@"0%ld:0%ld",second/60,second%60];
        }
        return [NSString stringWithFormat:@"0%ld:%ld",second/60,second%60];
    } else if (second < 3600){
        if (second % 60 < 10) {
            return [NSString stringWithFormat:@"%ld:0%ld",second/60,second%60];
        }
        return [NSString stringWithFormat:@"%ld:%ld",second/60,second%60];
    } else {
        if (second % 60 < 10 && (second%3600)/60 < 10) {
            return [NSString stringWithFormat:@"%ld:0%ld:0%ld",second/3600,(second%3600)/60,second%60];
        }
        if ((second%3600)/60 < 10) {
            return [NSString stringWithFormat:@"%ld:0%ld:%ld",second/3600,(second%3600)/60,second%60];
        }
        if (second % 60 < 10) {
            return [NSString stringWithFormat:@"%ld:%ld:0%ld",second/3600,(second%3600)/60,second%60];
        }
        return [NSString stringWithFormat:@"%ld:%ld:%ld",second/3600,(second%3600)/60,second%60];
    }
}

#pragma mark 根据size截取图片中间矩形区域的图片 这里的size是正方形
-(UIImage *)cutCenterImage:(UIImage *)image size:(CGSize)size{
    CGSize imageSize = image.size;
    CGRect rect;
    //根据图片的大小计算出图片中间矩形区域的位置与大小
    if (imageSize.width > imageSize.height) {
        float leftMargin = (imageSize.width - imageSize.height) * 0.5;
        rect = CGRectMake(leftMargin, 0, imageSize.height, imageSize.height);
    }else{
        float topMargin = (imageSize.height - imageSize.width) * 0.5;
        rect = CGRectMake(0, topMargin, imageSize.width, imageSize.width);
    }
    
    CGImageRef imageRef = image.CGImage;
    //截取中间区域矩形图片
    CGImageRef imageRefRect = CGImageCreateWithImageInRect(imageRef, rect);
    
    UIImage *tmp = [[UIImage alloc] initWithCGImage:imageRefRect];
    CGImageRelease(imageRefRect);
    
    UIGraphicsBeginImageContext(size);
    CGRect rectDraw = CGRectMake(0, 0, size.width, size.height);
    [tmp drawInRect:rectDraw];
    // 从当前context中创建一个改变大小后的图片
    tmp = UIGraphicsGetImageFromCurrentImageContext();
    
    // 使当前的context出堆栈
    UIGraphicsEndImageContext();
    
    return tmp;
}

-(int)isJPEGValid:(NSData *)jpeg{
    if ([jpeg length] < 4){
        return 1;
    }
    const unsigned char * bytes = (const unsigned char *)[jpeg bytes];
    if (bytes[0] != 0xFF || bytes[1] != 0xD8) {
        return 2;
    }
    
    if (bytes[[jpeg length] - 2] != 0xFF || bytes[[jpeg length] - 1] != 0xD9) {
        return 3;
    }
    return 0;
}

+ (UIImage *)captureScreen:(UIView *)view {
    CGRect rect = [view bounds];
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    [view.layer renderInContext:context];
    UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return img;
}
@end

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark - 实体

@implementation QFAsset

- (instancetype)init
{
    self = [super init];
    if (self) {
        self.isExist = NO;
    }
    return self;
}

- (void)dealloc
{
    self.fileID = nil;
    self.url = nil;
    self.fileName = nil;
    self.createDate = nil;
    self.duration = nil;
    self.thumbnail = nil;
}
@end
